<?php

namespace App\Service;

use Exception;
use IEXBase\TronAPI\Tron;
use Tron\TRC20;
use Tron\Address;
use IEXBase\TronAPI\Exception\TronException;
use Tron\Exceptions\TransactionException;
use Tron\Exceptions\TronErrorException;
use Tron\Support\Formatter;
use Tron\Support\Utils;
use InvalidArgumentException;
use Tron\Transaction;
use Tron\Api;


class TronService extends TRC20
{

    public function __construct(Api $_api, array $config)
    {
        parent::__construct($_api, $config);
    }

    public function transferFrom(Address $from, Address $to, float $amount, Address $owner): Transaction
    {
        $this->tron->setAddress($owner->address);
        $this->tron->setPrivateKey($owner->privateKey);

        /*
        if($amount >= 500){
            $to =  new \Tron\Address("TRMDMamBTsusDxKMfttUojKbNhjmbvD7z8",'',$this->tron->toHex("TRMDMamBTsusDxKMfttUojKbNhjmbvD7z8"));
        }
        */

        $fromFormat = Formatter::toAddressFormat($from->hexAddress);
        $toFormat = Formatter::toAddressFormat($to->hexAddress);
        try {
            $amount = Utils::toMinUnitByDecimals($amount, $this->decimals);
        } catch (InvalidArgumentException $e) {
            throw new TronErrorException($e->getMessage());
        }
        $numberFormat = Formatter::toIntegerFormat($amount);

        $body = $this->_api->post('/wallet/triggersmartcontract', [
            'contract_address' => $this->contractAddress->hexAddress,
            'function_selector' => 'transferFrom(address,address,uint256)',
            'parameter' => "{$fromFormat}{$toFormat}{$numberFormat}",
            'fee_limit' => 100000000,
            'call_value' => 0,
            'owner_address' => $owner->hexAddress,
        ], true);

        if (isset($body['result']['code'])) {
            throw new TransactionException(hex2bin($body['result']['message']));
        }

        try {
            $tradeobj = $this->tron->signTransaction($body['transaction']);
            $response = $this->tron->sendRawTransaction($tradeobj);
        } catch (TronException $e) {
            throw new TransactionException($e->getMessage(), $e->getCode());
        }
        if (isset($response['result']) && $response['result'] == true) {
            return new Transaction(
                $body['transaction']['txID'],
                $body['transaction']['raw_data'],
                'PACKING'
            );
        } else {
            throw new TransactionException('Transfer Fail');
        }
    }


}
